/*
 * @Description: 
 * @Version: 2.0
 * @Autor: liuwei
 * @Date: 2021-05-27 10:40:02
 * @LastEditors: liuwei
 * @LastEditTime: 2021-05-29 09:42:45
 */
class Observer {
  constructor (data) {
    this.walk(data)
  }
  walk(data) {
    // 1.判断data是否是对象
    if (!data || typeof data !== 'object' ) return
    // 2.遍历data对象的所有属性
    Object.keys(data).forEach(key => {
      this.defineReactive(data, key, data[key])
    })
  }
  // 为什么要传第三个参数value，如果在get里直接返回obj[key]，则会发生死循环
  defineReactive (obj, key, value) {
    let that = this
    // 负责收集依赖，并发送通知
    let dep = new Dep()
    // 如果val是对象，则把对象内部的数据也转换成响应式数据
    this.walk(value)
    Object.defineProperty(obj, key, {
      enumerable: true,
      configurable: true,
      get () {
        // 收集对象
        Dep.target && dep.addSub(Dep.target)
        return value
      },
      set (newValue) {
        if ( newValue === value ) return
        value = newValue
        // 如果newValue是对象的话，则需要再次调用walk
        that.walk(newValue)
        // 发送通知
        dep.notify()
      }
    })
  }
}